package org.chungyan5.multiplenestingtagging.mobile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

import org.chungyan5.multiplenestingtagging.DbConn;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

/**
 * Mobile Android User Interface for This Multiple Nesting Tagging Library
 * 
 * @author yan
 *
 */
public class MNTMobile extends Activity {
	
	private long selectedStuffId[] = new long[2];	// [TAG_ID_INDEX] as selectedTagId, [ITEM_ID_INDEX] as selectedItemId
	private final int TAG_ID_INDEX = 0;
	private final int ITEM_ID_INDEX = 1;

	/**
	 * implementation of Spinner item selector 
	 * 
	 * @author yan
	 *
	 */
	class OnStuffSelectedListenerImp implements OnItemSelectedListener {

		private TextView testView;
		private int idIndex;
		
		public OnStuffSelectedListenerImp(TextView testView, int idIndex) {
			this.testView = testView;
			this.idIndex = idIndex;
		}
		
		@Override
		public void onItemSelected(AdapterView<?> parent, View view, int position,
				long id) {
			Cursor cur = (Cursor) parent.getItemAtPosition(position);
			cur.moveToPosition(position);
			selectedStuffId[idIndex] = cur.getLong(0);			// id is in Column 0 for this table design
			testView.setText(cur.getString(1));					// name is in Column 1 for this table design		
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
			// Do nothing.
		}
		
	}
	
	/**
	 * Handle Modification Click Handler
	 * 
	 * @author yan
	 *
	 */
	class ModificationOnClickListenerImp implements OnClickListener {

		private TextView testView;
		private String stuffColName;
		private String stuffColId;
		private Uri uri;
		private int idIndex;

		public ModificationOnClickListenerImp(TextView testView, String stuffColName, String stuffColId, Uri uri, int idIndex) {
			this.testView = testView;
			this.stuffColName = stuffColName;
			this.stuffColId = stuffColId;
			this.uri = uri;
			this.idIndex = idIndex;
		}
		
		@Override
		public void onClick(View v) {
			ContentValues values = new ContentValues();
			values.put(stuffColName, testView.getText().toString());
			
			values.put(stuffColId, selectedStuffId[idIndex]);
			getContentResolver().update(uri, values, null, null);
			testView.setText("");
		}
		
	}
	
    public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);
	    
	    // Tag =================================
        
        //	Click to add a Tag ===================
        Button buttonTag = (Button) findViewById(R.id.ButtonNewTag);
        buttonTag.setOnClickListener(new OnClickListener() {

    		@Override
    		public void onClick(View v) {
    			TextView testView = (TextView) findViewById(R.id.EditTextTag);
    			ContentValues values = new ContentValues();
    			values.put(DbConn.TABLE_TAG_COL_TAG_NAME, testView.getText().toString());
    			Uri uri = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.TAGS_PATH);
    			uri = getContentResolver().insert(uri, values);
    			testView.setText("");
    		}
        	
        });

        //	load db and display on spinner ===================
        Spinner spinnerTag = (Spinner) findViewById(R.id.SpinnerTag);
		Uri uriTag = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.TAGS_PATH);
        Cursor curTag = managedQuery(uriTag, new String[] {DbConn.TABLE_TAG_COL_TAG_PTR, DbConn.TABLE_TAG_COL_TAG_NAME}, null, null, null);
        SimpleCursorAdapter adapterTag = new SimpleCursorAdapter(this
        		, android.R.layout.simple_spinner_item, curTag
        		, new String[] { DbConn.TABLE_TAG_COL_TAG_PTR, DbConn.TABLE_TAG_COL_TAG_NAME }
        		, new int[] {android.R.id.text2, android.R.id.text1});
        adapterTag.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        adapterTag.notifyDataSetChanged();
        spinnerTag.setAdapter(adapterTag);
        
        //	get the selection for modification ===================
        OnStuffSelectedListenerImp onTagSelectedListenerImp = 
        	new OnStuffSelectedListenerImp((TextView) findViewById(R.id.EditTextModifyTag), TAG_ID_INDEX);
        spinnerTag.setOnItemSelectedListener(onTagSelectedListenerImp);
        Button buttonModifyTag = (Button) findViewById(R.id.ButtonModifyTag);
		ModificationOnClickListenerImp onClickTagListenerImp = new ModificationOnClickListenerImp((TextView) findViewById(R.id.EditTextModifyTag)
				, DbConn.TABLE_TAG_COL_TAG_NAME, DbConn.TABLE_TAG_COL_TAG_PTR
				, Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.TAGS_PATH), TAG_ID_INDEX);
        buttonModifyTag.setOnClickListener(onClickTagListenerImp);

        //	remove a tag ===================
        Button buttonDelTag = (Button) findViewById(R.id.ButtonDelTag);
        buttonDelTag.setOnClickListener(new OnClickListener() {

    		@Override
    		public void onClick(View v) {
    			TextView testView = (TextView) findViewById(R.id.EditTextModifyTag);
    			
    			Uri uri = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.TAGS_PATH);
    			getContentResolver().delete(uri, Long.toString(selectedStuffId[TAG_ID_INDEX]), null);
    			testView.setText("");
    		}
        	
        });

	    // Tag attach Items =============================
        Button buttonTagAttachItems = (Button) findViewById(R.id.ButtonChange2TagAttachItemActivity);
        buttonTagAttachItems.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Bundle bundle = new Bundle();
				bundle.putLong("id", selectedStuffId[TAG_ID_INDEX]);
				Intent myIntent = new Intent(v.getContext(), TagAttachItems.class);
				myIntent.putExtras(bundle);
				startActivityForResult(myIntent, 0);
			}
		});

	    // Restore database =============================
        Button buttonRestore = (Button) findViewById(R.id.ButtonRestore);
        buttonRestore.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
		        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) 
					Toast.makeText(MNTMobile.this, "Pls mount SD Card", Toast.LENGTH_SHORT);
		        else {
		        	AlertDialog.Builder builder = new AlertDialog.Builder(MNTMobile.this);
		        	builder.setMessage("Are you sure to restore?")
		        	       .setCancelable(false)
		        	       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
		        	           public void onClick(DialogInterface dialog, int id) {
		        	        	   new RestoreDatabaseFileTask().execute();        
		        	           }
		        	       })
		        	       .setNegativeButton("No", new DialogInterface.OnClickListener() {
		        	           public void onClick(DialogInterface dialog, int id) {
		        	                dialog.cancel();
		        	           }
		        	       });
	        		builder.create().show();
		        }
			}
			
		});

        
	    // Item =================================
        
        //	Click to add a Item ===================
        Button buttonItem = (Button) findViewById(R.id.ButtonAddItem);
        buttonItem.setOnClickListener(new OnClickListener() {

    		@Override
    		public void onClick(View v) {
    			TextView testView = (TextView) findViewById(R.id.EditTextAddItem);
    			ContentValues values = new ContentValues();
    			values.put(DbConn.TABLE_ITEM_COL_ITEM_NAME, testView.getText().toString());
    			Uri uri = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.ITEMS_PATH);
    			uri = getContentResolver().insert(uri, values);
    			testView.setText("");
    		}
        	
        });

        //	load db and display on spinner ===================
        Spinner spinnerItem = (Spinner) findViewById(R.id.SpinnerItem);
		Uri uriItem = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.ITEMS_PATH);
		Cursor curItem = managedQuery(uriItem, new String[] {DbConn.TABLE_ITEM_COL_ITEM_PTR, DbConn.TABLE_ITEM_COL_ITEM_NAME}, null, null, null);
        SimpleCursorAdapter adapterItem = new SimpleCursorAdapter(this
        		, android.R.layout.simple_spinner_item, curItem
        		, new String[] { DbConn.TABLE_ITEM_COL_ITEM_PTR, DbConn.TABLE_ITEM_COL_ITEM_NAME }
        		, new int[] {android.R.id.text2, android.R.id.text1});
        adapterItem.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        adapterItem.notifyDataSetChanged();
        spinnerItem.setAdapter(adapterItem);
        
        //	get the selection for modification ===================
        OnStuffSelectedListenerImp onItemSelectedListenerImp = 
        	new OnStuffSelectedListenerImp((TextView) findViewById(R.id.EditTextModifyItem), ITEM_ID_INDEX);
        spinnerItem.setOnItemSelectedListener(onItemSelectedListenerImp);
        Button buttonModifyItem = (Button) findViewById(R.id.ButtonModifyItem);
		ModificationOnClickListenerImp onClickItemListenerImp = new ModificationOnClickListenerImp((TextView) findViewById(R.id.EditTextModifyItem)
				, DbConn.TABLE_ITEM_COL_ITEM_NAME, DbConn.TABLE_ITEM_COL_ITEM_PTR
				, Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.ITEMS_PATH), ITEM_ID_INDEX);
		buttonModifyItem.setOnClickListener(onClickItemListenerImp);
		
        //	remove a Item ===================
        Button buttonDelItem = (Button) findViewById(R.id.ButtonDelItem);
        buttonDelItem.setOnClickListener(new OnClickListener() {

    		@Override
    		public void onClick(View v) {
    			TextView testView = (TextView) findViewById(R.id.EditTextModifyItem);
    			
    			Uri uri = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.ITEMS_PATH);
    			getContentResolver().delete(uri, Long.toString(selectedStuffId[ITEM_ID_INDEX]), null);
    			testView.setText("");
    		}
        	
        });

        
	    // Item attach Tags =============================
        Button buttonItemAttachTags = (Button) findViewById(R.id.ButtonChange2ItemAttachTagActivity);
        buttonItemAttachTags.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Bundle bundle = new Bundle();
				bundle.putLong("id", selectedStuffId[ITEM_ID_INDEX]);
				Intent myIntent = new Intent(v.getContext(), ItemAttachTags.class);
				myIntent.putExtras(bundle);
				startActivityForResult(myIntent, 0);
			}
		});

	    // Backup database =============================
        Button buttonBackup = (Button) findViewById(R.id.ButtonBackup);
        buttonBackup.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
		        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) 
					Toast.makeText(MNTMobile.this, "Pls mount SD Card", Toast.LENGTH_SHORT);
		        else {
		        	AlertDialog.Builder builder = new AlertDialog.Builder(MNTMobile.this);
		        	builder.setMessage("Are you sure to export?")
		        	       .setCancelable(false)
		        	       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
		        	           public void onClick(DialogInterface dialog, int id) {
		        	        	   new ExportDatabaseFileTask().execute();        
		        	           }
		        	       })
		        	       .setNegativeButton("No", new DialogInterface.OnClickListener() {
		        	           public void onClick(DialogInterface dialog, int id) {
		        	                dialog.cancel();
		        	           }
		        	       });
		        	AlertDialog alert = builder.create();
		        	alert.show();
		        }
			}
		});
        
	}
    
	private class ExportDatabaseFileTask extends AsyncTask<String, Void, Boolean> {

		private ProgressDialog dialog;

		// can use UI thread here
		protected void onPreExecute() {
			dialog = ProgressDialog.show(MNTMobile.this, "Mnt System", "Exporting database...");
		}

		// automatically done on worker thread (separate from UI thread)
		protected Boolean doInBackground(final String... args) {
			Uri uri = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.DB_PATH);
			Cursor cur = getContentResolver().query(uri, null, null, null, null);
			cur.moveToNext();
			if (cur.getInt(0)>=0) return true;
			else return false;
		}

		protected void onPostExecute(final Boolean success) {
			
			if (dialog.isShowing()) {
			    dialog.dismiss();
			}
			/*if (success) {
				dialog.setMessage("Export successful");
				Toast.makeText(MNTMobile.this, "Export successful", Toast.LENGTH_SHORT);
			} else {
				dialog.setMessage("Export successful");
				Toast.makeText(MNTMobile.this, "Export failed", Toast.LENGTH_SHORT);
			}*/
		}

   }
    
	private class RestoreDatabaseFileTask extends AsyncTask<String, Void, Boolean> {

		private final ProgressDialog dialog = new ProgressDialog(MNTMobile.this);

		// can use UI thread here
		protected void onPreExecute() {
			this.dialog.setMessage("Restoring database...");
			this.dialog.show();
		}

		// automatically done on worker thread (separate from UI thread)
		protected Boolean doInBackground(final String... args) {
			Uri uri = Uri.withAppendedPath(MNTContentProvider.CONTENT_URI, MNTContentProvider.DB_PATH);
			if (getContentResolver().update(uri, null, null, null)>=0) return true;
			else return false;
		}

		protected void onPostExecute(final Boolean success) {
			if (this.dialog.isShowing()) {
			    this.dialog.dismiss();
			}
			
			/*if (success) {
				Toast.makeText(MNTMobile.this, "Restore successful", Toast.LENGTH_SHORT);
			} else {
				Toast.makeText(MNTMobile.this, "Restore failed", Toast.LENGTH_SHORT);
			}*/
			Intent intent = getIntent();
			finish();
			startActivity(intent);

		}

   }
    
}